package br.com.network {
	import adobe.utils.CustomActions;
	import br.com.network.events.ConexaoEvent;
	import br.com.poliwar.model.AbsSubject;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.events.SecurityErrorEvent;
	import flash.net.ObjectEncoding;
	import flash.net.Socket;
	import flash.utils.Endian;
	import flash.utils.getDefinitionByName;
	import flash.utils.getQualifiedClassName;
	
	/**
	 * ...
	 * @author Ricardo Teixeira
	 */
	public class Conexao extends AbsSubject {
		
		private static var _instance:Conexao;
		
		private var socket:Socket;
		
		public function Conexao() {
			if (Conexao._instance != null) {
				throw new Error ("#error [Conexao]: não pode haver mais de uma instância da classe.");
			} else {
			
				this.socket = new Socket ();
				this.socket.objectEncoding = ObjectEncoding.AMF3;
				this.socket.addEventListener (ProgressEvent.SOCKET_DATA, onSocketData);
				this.socket.addEventListener (Event.CONNECT, onConnect);
				this.socket.addEventListener (Event.CLOSE, onClose);
				this.socket.addEventListener (IOErrorEvent.IO_ERROR, onError);
				this.socket.addEventListener (SecurityErrorEvent.SECURITY_ERROR, onSecurityError);
				
			}
		}
		
		public function conectar (host:String = "localhost", porta:int = 6667):void {
			this.socket.connect (host, porta);
		}
		
		public function enviar (dado:Object, tipo:String = ""):void {			
			var dataVO:DataVO = new DataVO (tipo, dado);
			this.socket.writeObject ("\0");
			this.socket.writeObject (dataVO);
			this.socket.flush ();
		}
		
		public  function receber ():Object {
			var obj:Object = this.socket.readObject ();
			trace ("receber", obj);
			return obj;
		}
		
		private function onSecurityError(e:SecurityErrorEvent):void {
			trace ("#onSecurityError [Conexao]: ", e);
		}
		
		private function onError(e:IOErrorEvent):void {
			trace ("#onError [Conexao]: ", e);
		}
		
		private function onClose(e:Event):void {
			var evento:ConexaoEvent = new ConexaoEvent (ConexaoEvent.CONEXAO_FECHADA);
			this.dispatchEvent (evento);
		}
		
		private function onConnect(e:Event):void {
			var evento:ConexaoEvent = new ConexaoEvent (ConexaoEvent.CONECTADO);
			this.dispatchEvent (evento);
		}
		
		private function onSocketData(e:ProgressEvent):void {
			trace ("Conexao: onSocketData");
			
			var evento:ConexaoEvent = new ConexaoEvent ( ConexaoEvent.RECEBE_DADO, this.socket.readObject() );
			this.dispatchEvent (evento);
		}
		
		public static function get instance():Conexao {
			if (Conexao._instance == null) {
				Conexao._instance = new Conexao ();
			}
			
			return Conexao._instance;
		}
	
		public function get conectado():Boolean { 
			return this.socket.connected;	
		}
		
	}
}